﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml.Serialization;
using Windows.Security.Credentials.UI;
using Windows.Web.Http;
using F2S.OAuth;
using HttpStatusCode = System.Net.HttpStatusCode;

namespace F2S.oAuth
{
    public class OAuthProcessor
    {
        private static Dictionary<System.Net.HttpStatusCode, OauthExecutionStatusCodes> _codeMap = new Dictionary<HttpStatusCode, OauthExecutionStatusCodes>()
        {
            {System.Net.HttpStatusCode.OK, OauthExecutionStatusCodes.OK },
            {System.Net.HttpStatusCode.Forbidden, OauthExecutionStatusCodes.Forbidden },
            {System.Net.HttpStatusCode.Unauthorized, OauthExecutionStatusCodes.Unauthorized }
        };

        static OAuthProcessor()
        {
        }

        public Task<AuthorizationResult> authorizeUser(AuthorizationRequest request)
        {
            var oauth = new OAuthBase();
            return null;
        }

        async public Task<OAuthExecutionResult<T>> execute<T>(OAuthExecutionRequest request) where T : class
        {
            var oauth = new OAuthBase(
                request.Credentials.UserCredentials.UserToken, request.Credentials.UserCredentials.UserSecret,
                request.Credentials.AppCredentials.ApiKey, request.Credentials.AppCredentials.ApiSecret);
            var response = await oauth.execute(request.Url, request.Method);

            return await processResponse<T>(response);
        }
        async public Task<OAuthExecutionResult> execute(string uri)
        {
            var client = new System.Net.Http.HttpClient();
            var result = await client.GetAsync(new Uri(uri));

            string data = null;
            if (result.IsSuccessStatusCode)
            {
                data = await result.Content.ReadAsStringAsync();
            }
            return new OAuthExecutionResult(result, data);
        }

        async public Task<OAuthExecutionResult<T>> execute<T>(string uri) where T : class
        {
            var client = new System.Net.Http.HttpClient();
            var result = await client.GetAsync(new Uri(uri));

            string data = null;
            T obj = default(T);

            if (result.IsSuccessStatusCode)
            {
                data = await result.Content.ReadAsStringAsync();
                obj = deserialize<T>(data);
            }
            return new OAuthExecutionResult<T>(result, data, obj);
        }

        async private Task<OAuthExecutionResult<T>> processResponse<T>(System.Net.Http.HttpResponseMessage response) where T : class
        {
            var data = await response.Content.ReadAsStringAsync();
            return new OAuthExecutionResult<T>(response, mapStatusCodes<T>(response.StatusCode), data, deserialize<T>(data));
        }

        private T deserialize<T>(string data) where T : class
        {
            try
            {
                var serializer = new XmlSerializer(typeof(T));
                using (var tr = new StringReader(data))
                {
                    var o = serializer.Deserialize(tr) as T;
                    return o;
                }
            }
            catch (Exception)
            {
            }

            return null;
        }

        private OauthExecutionStatusCodes mapStatusCodes<T>(System.Net.HttpStatusCode httpStatusCode) where T : class
        {
            var result = OauthExecutionStatusCodes.Other;
            _codeMap.TryGetValue(httpStatusCode, out result);
            return result;
        }
    }
}
